package com.xjoyt.pay.master.services;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import com.xjoyt.pay.abstracts.AbstractService;
import com.xjoyt.pay.commons.MoneyTypeUtils;
import com.xjoyt.pay.commons.ObjectUtils;
import com.xjoyt.pay.dto.PageParam;
import com.xjoyt.pay.dto.PageResult;
import com.xjoyt.pay.master.params.ChannelPageParam;
import com.xjoyt.pay.master.params.MerchantMoneyPageParam;
import com.xjoyt.pay.master.params.MerchantPageParam;
import com.xjoyt.pay.master.po.Channel;
import com.xjoyt.pay.master.po.Merchant;
import com.xjoyt.pay.master.po.MerchantMoney;
import com.xjoyt.pay.master.repository.ChannelRepository;
import com.xjoyt.pay.master.repository.MerchantMoneyRepository;
import com.xjoyt.pay.master.repository.MerchantRepository;
import com.xjoyt.pay.master.vo.ChannelGroup;
import com.xjoyt.pay.master.vo.MerchantMap;
import com.xjoyt.pay.master.vo.MerchantMoneyMap;
import com.xjoyt.pay.vo.MoneyType;

@Service
public class MerchantMoneyService extends AbstractService {

	@Autowired
	private MerchantMoneyRepository repository;

	@Autowired
	private MerchantRepository merchantRepository;

	@Autowired
	private ChannelRepository channelRepository;

	public PageResult<MerchantMap> loadPageGroup(@RequestBody PageParam<MerchantPageParam> param) {
		PageResult<Merchant> page = merchantRepository.loadPage(param);
		List<String> merchantIds = new ArrayList<>();
		List<MerchantMap> list = new ArrayList<>();
		for (Merchant item : page) {
			merchantIds.add(item.id);
			MerchantMap vo = new MerchantMap();
			list.add(vo);
			ObjectUtils.fieldCopy(item, vo);
		}
		if (CollectionUtils.isNotEmpty(merchantIds) && param.query != null || param.query.enabled) {
			List<Object[]> sum = repository.sumByMerchantIdInGroupByMerchantIdIn(merchantIds);
			for (Object[] objects : sum) {
				if (objects == null || objects.length != 2 || objects[0] == null)
					continue;
				Object merchantId = objects[0];
				for (MerchantMap item : list) {
					if (merchantId.equals(item.id)) {
						item.moneySum = objects[1] == null ? 0 : NumberUtils.toDouble(objects[1].toString());
						break;
					}
				}
			}
		}
		return new PageResult<>(page.getTotal(), list);

	}

	public PageResult<MerchantMoneyMap> loadPage(@RequestBody PageParam<MerchantMoneyPageParam> param) {

		PageResult<MerchantMoney> page = repository.loadPage(param);
		List<MerchantMoneyMap> list = new ArrayList<>();
		List<String> merchantIds = new ArrayList<>();
		for (MerchantMoney item : page) {
			merchantIds.add(item.merchant.id);
			MerchantMoneyMap vo = new MerchantMoneyMap();
			list.add(vo);
			ObjectUtils.fieldCopy(item, vo);
		}

		List<Object> footer = new ArrayList<>();
		if (CollectionUtils.isNotEmpty(merchantIds) && param.query != null || param.query.enabled) {
			List<Map<String, Object>> sum = repository.sum(merchantIds, param.query);
			list.forEach(item -> {
				for (MoneyType type : MoneyType.values()) {
					if (item.type == type) {
						item.name = MoneyTypeUtils.getName(type);
					}
				}
			});

			if (CollectionUtils.isNotEmpty(sum)) {
				for (Map<String, Object> map : sum) {
					if (map == null || !map.containsKey("id") || map.get("id") == null) {
						continue;
					}
					Map<String, Object> map1 = new HashMap<>();
					map1.put("merchantId", (map.containsKey("id") && map.get("id") != null) ? map.get("id") : 0);
					map1.put("moneySum", (map.containsKey("sum") && map.get("sum") != null) ? map.get("sum") : 0);
					footer.add(map1);
				}
			}
		}
		return new PageResult<>(page.getTotal(), list, footer);
	}

	public PageResult<ChannelGroup> loadPageChannel(@RequestBody PageParam<ChannelPageParam> param) {

		PageResult<Channel> channelPage = channelRepository.loadPage(param);
		List<ChannelGroup> list = new ArrayList<>();

		for (Channel item : channelPage) {
			ChannelGroup vo = new ChannelGroup();
			list.add(vo);
			ObjectUtils.fieldCopy(item, vo);
		}

		if (StringUtils.isNotEmpty(param.query.merchantId)) {
			List<Object[]> sum = repository.sumByMerchantIdGroupByChannelId(param.query.merchantId);
			for (Object[] objects : sum) {
				if (objects == null || objects.length != 2 || objects[0] == null) {
					continue;
				}
				Object channelId = objects[0];
				for (ChannelGroup item : list) {
					if (channelId.equals(item.id)) {
						item.moneySum = objects[1] == null ? 0 : NumberUtils.toDouble(objects[1].toString());
						break;
					}
				}
			}
		}

		return new PageResult<>(channelPage.getTotal(), list);
	}

}
